package com.ligongzzz.indoorlocation;

import androidx.appcompat.app.AppCompatActivity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.util.Base64;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONObject;
import org.w3c.dom.Text;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.MalformedInputException;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    WifiManager wifiManager;
    boolean requestWifiScan = false;
    ConnectThread connectThread;
    String detail;
    boolean isScanning = false, isCo = false;
    private SensorManager sensorManager;
    float lightLevel = 0;
    float[] accelerometerValues, magneticFieldValues;
    float deltaOri = 0, currentOri = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        wifiManager = (WifiManager)getApplicationContext().getSystemService(WIFI_SERVICE);

        BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context c, Intent intent) {
                boolean success = intent.getBooleanExtra(
                        WifiManager.EXTRA_RESULTS_UPDATED, false);
                if (!requestWifiScan){
                    return;
                }
                else{
                    requestWifiScan = false;
                }
                if (success) {
                    onRSSISuccess(c);
                }
                else{
                    Toast.makeText(c, "Scan Failed!", Toast.LENGTH_SHORT).show();
                }
            }
        };

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        this.registerReceiver(wifiScanReceiver, intentFilter);

        //设置随机数
        SharedPreferences sharedPreferences= getSharedPreferences("data", Context .MODE_PRIVATE);
        String userID = sharedPreferences.getString("ID", "");

        if(userID.equals("")){
            Integer randomID = (int)(1+Math.random()*100000);
            userID = randomID.toString();
        }
        EditText editText = (EditText)findViewById(R.id.edittext1);
        editText.setText(userID.toString());

        //初始化灯光传感器
        //第一步：获取 SensorManager 的实例
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        //第二步：获取 Sensor 传感器类
        Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
        //第四步：注册 SensorEventListener
        sensorManager.registerListener(listener,sensor,SensorManager.SENSOR_DELAY_NORMAL);

        // 初始化加速度传感器
        Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        // 初始化地磁场传感器
        Sensor magnetic = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        //注册监听
        sensorManager.registerListener(listener, accelerometer, SensorManager.SENSOR_DELAY_UI);
        sensorManager.registerListener(listener, magnetic, SensorManager.SENSOR_DELAY_UI);
    }


    //第三步：对传感器信号进行监听
    private SensorEventListener listener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            if(event.sensor.getType()==Sensor.TYPE_LIGHT) {
                //提示当前光照强度
                TextView textView = (TextView) findViewById(R.id.textLight);
                textView.setText("当前光照强度：" + event.values[0]);
                lightLevel = event.values[0];
            }
            else {
                if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                    accelerometerValues = event.values;
                }
                if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
                    magneticFieldValues = event.values;
                }
                if (accelerometerValues!=null && magneticFieldValues!=null) {
                    calculateOrientation();
                }
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {

        }
    };

    private void calculateOrientation() {
        float[] values = new float[3];
        float[] r = new float[9];
        SensorManager.getRotationMatrix(r, null, accelerometerValues, magneticFieldValues);
        SensorManager.getOrientation(r, values);
        values[0] = (float) Math.toDegrees(values[0]);
        float orientation = values[0];
        orientation += deltaOri;
        orientation = orientation % 360;
        if(orientation<0){
            orientation += 360;
        }
        TextView textView = (TextView)findViewById(R.id.textOri);
        textView.setText("当前方向角："+orientation);
        currentOri = orientation;
    }

    public void onRSSISuccess(Context c){
        //Toast.makeText(c, "扫描成功！", Toast.LENGTH_SHORT).show();
        List<ScanResult> scanWifiList = wifiManager.getScanResults();
        List<Pair<String, Integer>> wifiRSSIList = new ArrayList<>();
        Log.e("WIFI SIZE:",String.valueOf(scanWifiList.size()));
        String RSSIResultStr = "";

        RSSIResultStr += "WIFI数量:"+scanWifiList.size()+"\n";
        JSONObject jsonObject = new JSONObject();
        // Get ID
        EditText editText = (EditText)findViewById(R.id.edittext1);
        String userID = editText.getText().toString();

        // Save user ID
        SharedPreferences sharedPreferences= getSharedPreferences("data",Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("ID", userID);
        editor.commit();

        JSONObject RSSIMap = new JSONObject();

        if (scanWifiList != null && scanWifiList.size() > 0) {
            for (int i = 0; i < scanWifiList.size(); i++) {
                ScanResult scanResult = scanWifiList.get(i);
                if (!scanResult.SSID.isEmpty()) {
                    String key = "SSID:"+scanResult.SSID + " MAC:" + scanResult.BSSID;
                    wifiRSSIList.add(new Pair<String, Integer>(key, scanResult.level));
                    RSSIResultStr += key +" RSSI:" +String.valueOf(scanResult.level) + "\n";
                    JSONObject MACInfo = new JSONObject();
                    try{
                        MACInfo.put("SSID", scanResult.SSID);
                        MACInfo.put("RSSI", scanResult.level);

                        RSSIMap.put(scanResult.BSSID, MACInfo);
                    }
                    catch (Exception e){
                        e.printStackTrace();
                        Toast.makeText(this, "JSON错误",Toast.LENGTH_SHORT).show();
                        return;
                    }
                }
            }

            try {
                jsonObject.put("ID", userID);
                jsonObject.put("RSSIMap", RSSIMap);
                jsonObject.put("LightLevel", lightLevel);
                jsonObject.put("Ori", currentOri);
                jsonObject.put("Co", isCo);
            }
            catch (Exception e){
                e.printStackTrace();
                Toast.makeText(this, "JSON错误",Toast.LENGTH_SHORT).show();
                return;
            }

            // HTML
            getHTMLData(jsonObject.toString());
        }else {
            Toast.makeText(c,"没有找到附近的WIFI信号。", Toast.LENGTH_SHORT).show();
            return;
        }
        TextView textView=(TextView)findViewById(R.id.text1);
        textView.setText("扫描已经成功！");
    }


    public void onGetRSSIClicked(View view){
        Button button = (Button)findViewById(R.id.button1);
        if(isScanning){
            isScanning = false;
            button.setText("开始扫描");
        }
        else {
            isScanning = true;
            sendScanSignal();
            button.setText("结束扫描");
        }
    }

    public void onChangeCoClicked(View view){
        Button button = (Button)findViewById(R.id.button3);
        if(isCo){
            isCo = false;
            button.setText("打开协同定位");
        }
        else{
            isCo = true;
            button.setText("关闭协同定位");
        }
    }

    public void onResetOriClicked(View view){
        deltaOri = (-(currentOri - deltaOri)) % 360;
        if(deltaOri < 0){
            deltaOri += 360;
        }
    }

    public void sendScanSignal(){
        if(!isScanning){
            return;
        }
        WifiManager wifiManager = (WifiManager)getApplicationContext().getSystemService(WIFI_SERVICE);
        if (wifiManager == null){
            Toast.makeText(this,"Failed to initialize wifi manager!", Toast.LENGTH_SHORT).show();
            return;
        }

        wifiManager.startScan();
        requestWifiScan = true;
        TextView textView=(TextView)findViewById(R.id.text1);
        textView.setText("扫描中，请稍后...");
    }


    public void showHTML(String html){
        ImageView imageView = (ImageView)findViewById(R.id.imageView);

        Bitmap bitmap = null;
        byte[] bitmapArray = Base64.decode(html, Base64.DEFAULT);
        bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
        imageView.setImageBitmap(bitmap);
    }

    private void handleResult(String result){
        try {
            JSONObject jsonObject = new JSONObject(result);
            int resultValue = jsonObject.getInt("result");
            if(resultValue==0){
                String resultAnswer = jsonObject.getString("answer");
                //Toast.makeText(MainActivity.this, resultAnswer, Toast.LENGTH_SHORT).show();
                TextView textView = (TextView)findViewById(R.id.text1);
                textView.setText(resultAnswer);
                showHTML(jsonObject.getString("image"));
                sendScanSignal();
            }
            else if(resultValue==1){
                // 需要重新发送
                sendScanSignal();
            }
            else if(resultValue==2){
                // Toast.makeText(MainActivity.this, "无定位结果", Toast.LENGTH_SHORT).show();
                sendScanSignal();
            }
        }
        catch (Exception e){
            e.printStackTrace();
            Toast.makeText(MainActivity.this, "Server Error!", Toast.LENGTH_SHORT).show();
            sendScanSignal();
        }
    }


    private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case 0x0:
                    //Toast.makeText(MainActivity.this, detail, Toast.LENGTH_SHORT).show();
                    handleResult(detail);
                default:
                    break;
            }
        };
    };


    public void getHTMLData(final String toSend){
        new Thread() {
            public void run() {
                try {
                    String URL = "http://ligongzzz.top/rssi";
                    String sendContent = URLEncoder.encode(toSend, "UTF-8");
                    URL += "?" + "test=" + sendContent;
                    detail = GetData.getHtml(URL);
                } catch (Exception e) {
                    e.printStackTrace();
                    detail = "Error";
                }
                handler.sendEmptyMessage(0x0);
            };
        }.start();
    }
}
